<template>
  <div class="main-content">
    <div class="app-header">
      <div class="go-back" @click="routerOpen('/')">
        <span class="fa fa-angle-left back-icon"></span>
        <span>返回</span>
      </div>
    </div>
    
    <div class="config-box">
      <zi-note class="notice" v-show="note.show" :type="note.type">
        <span>{{ note.content }}</span>
        <span class="close-notice" @click="closeNotice">X</span>
      </zi-note>
      <div class="preview-screen" :style="{ width: canvasWidth + 'px', height: canvasHeight + 'px' }">
        <canvas id="c" :width="canvasWidth" :height="canvasHeight"></canvas>
      </div>
      <zi-row class="form-row">
        <zi-col :span="8" class="form-label _required">
          <zi-tooltip class="label-tooltip" content="生成的图片模板" placement="top">
            <span>当前模板</span>
          </zi-tooltip>
        </zi-col>
        <zi-col :span="16" class="form-input">
          <span>{{ template.name }}</span>
          <!-- <div class="template-preview">
            <img class="template-img" :src="template.preview" alt="template-preview">
          </div> -->
        </zi-col>
      </zi-row>

      <zi-row class="form-row">
        <zi-col :span="8" class="form-label _required">
          <zi-tooltip class="label-tooltip" content="更换贴图蒙版的背景" placement="top">
            <span>更换蒙版背景</span>
          </zi-tooltip>
        </zi-col>
        <zi-col :span="16" class="form-input">
          <div>
            <zi-button size="small" @click.native="changeCanvasBg">选择图片</zi-button>
          </div>
          <div style="padding-top: 10px;">
            <zi-button size="small" @click.native="removeBg">移除背景</zi-button>
          </div>
        </zi-col>
      </zi-row>

      <zi-row class="form-row">
        <zi-col :span="8" class="form-label _required">
          <zi-tooltip class="label-tooltip" content="添加文字内容到视频蒙版（可自由缩放可移动；可多次添加）" placement="top">
            <span>添加文字内容</span>
          </zi-tooltip>
        </zi-col>
        <zi-col :span="16" class="form-input">
          <div>
            <zi-button size="small" @click.native="addTextToCanvas">添加文字</zi-button>
          </div>
        </zi-col>
      </zi-row>

      <zi-row class="form-row">
        <zi-col :span="8" class="form-label _required">
          <zi-tooltip class="label-tooltip" content="添加贴图内容到视频蒙版（可自由缩放可移动；可多次添加）" placement="top">
            <span>添加贴图</span>
          </zi-tooltip>
        </zi-col>
        <zi-col :span="16" class="form-input">
          <div>
            <zi-button size="small" @click.native="addImageToCanvas">添加贴图</zi-button>
          </div>
        </zi-col>
      </zi-row>

      
      <zi-row class="form-row">
        <zi-col :span="8" class="form-label _required">
          <zi-tooltip class="label-tooltip" content="决定视频如何调整尺寸" placement="top">
            <span>缩放方式</span>
          </zi-tooltip>
        </zi-col>
        <zi-col :span="16" class="form-input">
          <div>
            <zi-radio-group v-model="resizeType">
              <zi-radio label="1">强制填充（画面可能会变形）</zi-radio>
              <zi-radio label="2">填充背景模糊</zi-radio>
              <zi-radio label="3">裁切</zi-radio>
            </zi-radio-group>
          </div>
        </zi-col>
      </zi-row>

      <zi-row class="form-row">
        <zi-col :span="8" class="form-label">
          <zi-tooltip class="label-tooltip" content="需要替换的音频背景（可选）" placement="top">
            <span>替换音频</span>
          </zi-tooltip>
        </zi-col>
        <zi-col :span="16" class="form-input">
          <div>
            <zi-button size="small" @click.native="selectReplaceAudio">Select Audio</zi-button>
          </div>
          <div class="preview-creative" v-show="replaceAudio">
            <p>{{ replaceAudio }}</p>
          </div>
        </zi-col>
      </zi-row>

      <zi-row class="form-row">
        <zi-col :span="8" class="form-label _required">
          <zi-tooltip class="label-tooltip" content="选择需要批量处理的视频素材（可多选）" placement="top">
            <span>选择视频素材</span>
          </zi-tooltip>
        </zi-col>
        <zi-col :span="16" class="form-input">
          <div>
            <zi-button size="small" @click.native="selectVideoAssets">Select Videos</zi-button>
          </div>
          <div class="preview-creative">
            <zi-files :files="fileTree" @file-click="clickFileHandler" style="padding: 15px 0 0 0;"></zi-files>
          </div>
        </zi-col>
      </zi-row>

      <zi-row class="form-row action-btn-row">
        <zi-col :span="8" class="form-label"></zi-col>
        <zi-col :span="16" class="form-input">
          <zi-button type="success" shadow @click.native="submitHandler" :loading="loading">立即生成</zi-button>
          <zi-button @click.native="clearForm" :loading="loading" style="width: 150px;min-width: 150px;">Clear</zi-button>
          <!-- <zi-button @click.native="changeTest" :loading="loading" style="width: 150px;min-width: 150px;">resize</zi-button> -->
        </zi-col>
      </zi-row>

      <zi-row class="form-row" v-show="progress.show">
        <zi-col :span="8" class="form-label">
          <span>生成进度</span>
        </zi-col>
        <zi-col :span="10" class="form-input">
          <zi-progress :percentage="progress.percentage" color="#67c23a" :show-text="false"></zi-progress>
        </zi-col>
        <zi-col :span="6" class="progress-tip lh-32">{{ progress.text }}</zi-col>
      </zi-row>
    </div>

    <zi-dialog v-model="dialog1.visible" cancel="取消" done="确认" :beforeDone="confirmDelImage">
      <p>是否删除选中项？</p>
    </zi-dialog>

    <zi-dialog
      v-model="textForm.visible"
      cancel="取消"
      done="确认"
      title="请输入文字"
      width="500px"
      :beforeDone="confirmText"
      :closeByModal="false"
    >
      <div class="flex-left" style="margin-bottom: 15px;">
        <div class="unit-0 form-label _required" style="width: 100px;">
          <span>文字内容</span>
        </div>
        <div class="unit">
          <zi-input value="" size="small" v-model="textForm.text" style="width: 100%;"></zi-input>
        </div>
      </div>
      <div class="flex-left" style="margin-bottom: 15px;">
        <div class="unit-0 form-label" style="width: 100px;">
          <span>字体文件</span>
        </div>
        <div class="unit">
          <zi-button size="small" @click.native="chooseFontFile">选择字体</zi-button>
          <div class="preview-creative" v-show="textForm.font">
            <p>{{ textForm.fontPath }}</p>
          </div>
        </div>
      </div>
    </zi-dialog>
  </div>
</template>

<script>
  import path from 'path'
  import fs from 'fs'
  import ffmpeg from 'fluent-ffmpeg'
  import ffmpegPath from 'ffmpeg-static'
  import _ from 'lodash'
  import canvasBuffer from '@/services/electron-canvas-to-buffer'
  import makeDir from 'make-dir'
  import shell from 'any-shell-escape'
  import { exec } from 'child_process'
  import utils from '@/services/utils'
  import remoteTools from '@/services/remoteTools'
  import videoTools from '@/services/videoTools'

  export default {
    name: 'template-1',
    data () {
      return {
        canvasWidth: 360,
        canvasHeight: 640,
        note: {
          show: false,
          type: 'success',
          content: ''
        },
        dialog1: {
          visible: false,
          video: '',
        },
        progress: {
          show: false,
          percentage: 0,
          text: '开始生成'
        },
        template: {
          id: 'template-1',
          name: '720x1280 竖版视频',
          preview: 'static/imgs/template-1-demo.png'
        },
        videos: [],
        resizeType: '2', // 视频拉伸方式 1、填充（画面可能会变形）; 2、填充背景模糊; 3、裁切
        replaceAudio: '',
        loading: false,
        bgImgUrl: 'static/imgs/template1-cover.png',
        textForm: {
          visible: false,
          text: '',
          font: '',
          fontPath: '',
          color: '#666666',
        },
        __canvas: null,
      }
    },
    computed: {
      fileTree: function() {
        return this.videos.map( item => {
          return {
            type: 'file',
            name: path.basename(item),
            path: item
          }
        });
      },
    },
    mounted: function() {
      this.initCanvas();
    },
    methods: {
      routerOpen (link) {
        location.hash = `#${link}`
      },
      initCanvas() {
        var canvas = this.__canvas = new fabric.Canvas('c');
        this.renderBackground();
        // create a rect object
        var deleteIcon = "data:image/svg+xml,%3C%3Fxml version='1.0' encoding='utf-8'%3F%3E%3C!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'%3E%3Csvg version='1.1' id='Ebene_1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' width='595.275px' height='595.275px' viewBox='200 215 230 470' xml:space='preserve'%3E%3Ccircle style='fill:%23F44336;' cx='299.76' cy='439.067' r='218.516'/%3E%3Cg%3E%3Crect x='267.162' y='307.978' transform='matrix(0.7071 -0.7071 0.7071 0.7071 -222.6202 340.6915)' style='fill:white;' width='65.545' height='262.18'/%3E%3Crect x='266.988' y='308.153' transform='matrix(0.7071 0.7071 -0.7071 0.7071 398.3889 -83.3116)' style='fill:white;' width='65.544' height='262.179'/%3E%3C/g%3E%3C/svg%3E";

        var img = document.createElement('img');
        img.src = deleteIcon;

        function deleteObject(eventData, target) {
          var canvas = target.canvas;
          canvas.remove(target);
          canvas.requestRenderAll();
        }

        function renderIcon(ctx, left, top, styleOverride, fabricObject) {
          if (!this.getVisibility(fabricObject)) {
            return;
          }
          var size = this.cornerSize;
          ctx.save();
          ctx.translate(left, top);
          ctx.rotate(fabric.util.degreesToRadians(fabricObject.angle));
          ctx.drawImage(img, -size/2, -size/2, size, size);
          ctx.restore();
        }
        fabric.Object.prototype.controls.deleteControl = new fabric.Control({
          position: { x: 0.5, y: -0.5 },
          offsetY: 0,
          cursorStyle: 'pointer',
          mouseUpHandler: deleteObject,
          render: renderIcon,
          cornerSize: 20
        });
      },
      changeTest() {
        var canvas = this.__canvas;
        this.canvasWidth = 400;
        this.canvasHeight = 400;
        canvas.setWidth(this.canvasWidth);
        canvas.setHeight(this.canvasHeight);
      },
      renderBackground(bgImgWidth, bgImgHeight) {
        if (this.bgImgUrl) {
          var canvas = this.__canvas;
          // set background color
          const _bgImgWidth = bgImgWidth || 720;
          const _bgImgHeight = bgImgHeight || 1280;
          canvas.setBackgroundImage(this.bgImgUrl, canvas.renderAll.bind(canvas), {
              width: _bgImgWidth,
              height: _bgImgHeight,
              repeat: 'no-repeat',
              originX: 'left',
              originY: 'top',
              scaleX: canvas.width / _bgImgWidth,
              scaleY: canvas.height / _bgImgHeight,
          });
        }
      },
      removeBg() {
        var canvas = this.__canvas;
        if(canvas.backgroundImage) {
          this.bgImgUrl = '';
          canvas.backgroundImage = 0;
          canvas.renderAll();
        }
      },
      changeCanvasBg() {
        var _this = this;
        var imgFile = remoteTools.chooseSingleImage();
        if (imgFile) {
          var nativeImage = require('electron').nativeImage;
          var img = nativeImage.createFromPath(imgFile);
          var imgSize = img.getSize();
          // console.log(imgSize);
          if (this.__canvas) {
            fabric.Image.fromURL(img.toDataURL(), function(oImg) {
              _this.bgImgUrl = oImg;
              _this.renderBackground(imgSize.width, imgSize.height);
            });
          }
        }
      },
      confirmText() {
        var _this = this;
        if (!this.textForm.text) {
          this.$Toast.show({
            type: 'danger',
            text: '文字内容不能为空',
            duration: 4
          })
          return;
        }
        this.textForm.visible = false;
        if (this.__canvas) {
          var text = this.textForm.text;
          var textConf = {
            left: 100,
            top: 150,
            fill: _this.textForm.color,
            // fontFamily: '',
            fontSize: 20,
          };
          if (this.textForm.font) { textConf.fontFamily = this.textForm.font };
          var itext = new fabric.Text(text, textConf);

          this.__canvas.add(itext);
          this.__canvas.setActiveObject(itext);
        }
      },
      addImageToCanvas() {
        var _this = this;
        var imgFile = remoteTools.chooseSingleImage();
        if (imgFile) {
          var nativeImage = require('electron').nativeImage;
          var img = nativeImage.createFromPath(imgFile);
          var imgSize = img.getSize();
          var scale = 100 / imgSize.width;
          // console.log(imgSize);
          if (this.__canvas) {
            fabric.Image.fromURL(img.toDataURL(), function(oImg) {
              oImg.scale(scale).set({
                left: 100,
                top: 100,
              });
              _this.__canvas.add(oImg);
              _this.__canvas.setActiveObject(oImg);
            });
          }
        }
      },
      addTextToCanvas() {
        this.textForm = {
          visible: true,
          text: '',
          font: '',
          fontPath: '',
          color: '#666666',
        };
      },
      clearForm() {
        this.videos = [];
        this.replaceAudio = '';
        this.note = {
          show: false,
          type: 'success',
          content: ''
        };
        this.dialog1 = {
          visible: false,
          video: '',
        };
        this.progress = {
          show: false,
          percentage: 0,
          text: ''
        };
      },
      selectReplaceAudio() {
        this.replaceAudio = remoteTools.chooseSingleAudio();
      },
      chooseFontFile() {
        var _this = this;
        var fontPath = remoteTools.chooseSingleFont();
        var fontName = _.uniqueId('font_');
        // console.log(fontPath);
        // 动态引入 font
        var junction_font = new FontFace(fontName, `url(file://${fontPath})`);
        junction_font.load().then(function(loaded_face) {
          document.fonts.add(loaded_face);
          // document.body.style.fontFamily = '"Junction Regular", Arial';
          _this.textForm.font = fontName;
          _this.textForm.fontPath = fontPath;
        }).catch(function(error) {
          // error occurred
          console.log('load font error:');
          console.log(error);
        });
      },
      selectVideoAssets() {
        var paths = remoteTools.chooseVideos();
        // console.log(paths);
        this.videos = _.union(this.videos, paths);
        this.videos = _.uniq(this.videos);
      },
      clickFileHandler(e) {
        // console.log(e);
        // 移除选中项
        this.dialog1 = {
          visible: true,
          video: e.trigger.path,
        };
      },
      confirmDelImage() {
        const v = this.dialog1.video;
        this.videos = _.dropWhile(this.videos, function(o) { return o === v; });
        this.dialog1.visible = false;
        this.$Toast.show('移除成功');
      },
      closeNotice() {
        this.note = {
          show: false,
          type: 'success',
          content: ''
        }
      },
      async submitHandler() {
        // 取消 canvas 当前选中的对象
        this.__canvas && this.__canvas.discardActiveObject().renderAll(); 
        var _this = this;
        // 校验
        if(!this.videos.length) {
          this.note = {
            show: true,
            type: 'error',
            content: '请选择视频素材'
          }
          window.scroll(0, 0);
          return;
        }
        
        this.loading = true;
        // 开始生成
        const obj = {
          videos: this.videos,
          resizeType: this.resizeType,
          replaceAudio: this.replaceAudio,
        };
        console.log(obj);
        this.buildCreatives(obj);
      },
      async buildCreatives(options) {
        const _this = this;
        _this.progress = {
          show: true,
          percentage: 0,
          text: '开始生成'
        };
        let lastOutput = '';
        // 开始处理
        try {
          await makeDir(path.resolve(remoteTools.getDownloadDir(), 'video-batch-maker'));
          // 创建缓存文件夹
          await makeDir(path.resolve(remoteTools.getTmpDir(), 'inmobi'));
          let random = Math.floor(Math.random()*10000+0);
          let outputPath = path.resolve(remoteTools.getDownloadDir(), 'video-batch-maker', `output-${random}.mp4`);
          const videos = options.videos;
          const vnum = videos.length;
          console.log(`共有 ${vnum} 个视频素材`);
          // progress 提示
          _this.progress = {
            show: true,
            percentage: 0,
            text: `开始运行：0/${vnum}`
          };
          // 保存当前贴图蒙版
          let coverImg = await utils.saveCanvasToImage(document.getElementById('c'));
          await utils.sleep(300);
          // 合成视频
          for (let i = 0; i < vnum; i ++) {
            console.log('开始合成素材 ' + (i + 1) );
            _this.progress = {
              show: true,
              percentage: (i / vnum) * 100,
              text: `开始合成素材：${i + 1}/${vnum}`
            };
            let video = videos[i];
            lastOutput = await videoTools.makeTemplateVideo1(video, coverImg, options.resizeType, options.replaceAudio);
            console.log('素材 ' + (i + 1) + '合成成功' );
            _this.progress = {
              show: true,
              percentage: 0 / options.num,
              text: `素材合成成功：${i + 1}/${vnum}`
            };
            
          }

          _this.progress = {
            show: true,
            percentage: 100,
            text: `全部处理完成！`
          };
          console.log('全部处理完成！');
          _this.loading = false;
          _this.$Toast.show({
            type: 'success',
            text: '生成成功！文件输出位置："Downloads/video-batch-maker" ',
            duration: 10
          })
          _this.note = {
            show: true,
            type: 'success',
            content: '生成成功！文件输出位置："Downloads/video-batch-maker" '
          }
          // 打开输出文件夹
          remoteTools.showOutputFolder(lastOutput)
          // 清理缓存文件夹
          utils.delDir(path.resolve(remoteTools.getTmpDir(), 'inmobi'))
        } catch (error) {
          this.loading = false;
          console.log('生成出错！');
          console.log(error);
          _this.note = {
            show: true,
            type: 'error',
            content: '生成出错: ' + error.message
          }
        }
      }
    }
  }
</script>

<style>
  @import url('~@/assets/styles/main.css');
</style>